package com.fsserver.common.utils;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;

/**
 * 支付交易日志工具类
 * 用于记录支付相关操作日志
 * 
 * @author fsserver
 * @date 2025-03-13
 */
public class PaymentLogUtils {
    private static final Logger PAYMENT_LOGGER = LoggerFactory.getLogger("com.fsserver.core.service.payment");
    private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
    
    // 日志前缀常量
    private static final String PREFIX_PAYMENT_REQUEST = "支付请求";
    private static final String PREFIX_PAYMENT_RESPONSE = "支付响应";
    private static final String PREFIX_PAYMENT_NOTIFICATION = "支付通知";
    private static final String PREFIX_REFUND_REQUEST = "退款请求";
    private static final String PREFIX_REFUND_RESPONSE = "退款响应";
    private static final String PREFIX_RECONCILIATION = "对账记录";
    private static final String PREFIX_PAYMENT_ERROR = "支付错误";
    
    /**
     * 记录支付请求日志
     * 
     * @param paymentType 支付类型
     * @param orderNo 订单号
     * @param requestData 请求数据
     */
    public static void logPaymentRequest(String paymentType, String orderNo, Object requestData) {
        setBusinessId(orderNo);
        logPaymentOperation(PREFIX_PAYMENT_REQUEST, paymentType, orderNo, null, null, requestData);
    }
    
    /**
     * 记录支付响应日志
     * 
     * @param paymentType 支付类型
     * @param orderNo 订单号
     * @param responseData 响应数据
     */
    public static void logPaymentResponse(String paymentType, String orderNo, Object responseData) {
        logPaymentOperation(PREFIX_PAYMENT_RESPONSE, paymentType, orderNo, null, null, responseData);
    }
    
    /**
     * 记录支付通知日志
     * 
     * @param paymentType 支付类型
     * @param orderNo 订单号
     * @param notificationData 通知数据
     */
    public static void logPaymentNotification(String paymentType, String orderNo, Object notificationData) {
        setBusinessId(orderNo);
        logPaymentOperation(PREFIX_PAYMENT_NOTIFICATION, paymentType, orderNo, null, null, notificationData);
    }
    
    /**
     * 记录退款请求日志
     * 
     * @param paymentType 支付类型
     * @param orderNo 订单号
     * @param refundNo 退款号
     * @param requestData 请求数据
     */
    public static void logRefundRequest(String paymentType, String orderNo, String refundNo, Object requestData) {
        // 优先使用退款号作为业务ID
        if (!StringUtils.isEmpty(refundNo)) {
            MDCTraceUtils.setBusinessId(refundNo);
        } else {
            setBusinessId(orderNo);
        }
        
        logPaymentOperation(PREFIX_REFUND_REQUEST, paymentType, orderNo, refundNo, null, requestData);
    }
    
    /**
     * 记录退款响应日志
     * 
     * @param paymentType 支付类型
     * @param orderNo 订单号
     * @param refundNo 退款号
     * @param responseData 响应数据
     */
    public static void logRefundResponse(String paymentType, String orderNo, String refundNo, Object responseData) {
        logPaymentOperation(PREFIX_REFUND_RESPONSE, paymentType, orderNo, refundNo, null, responseData);
    }
    
    /**
     * 记录对账日志
     * 
     * @param paymentType 支付类型
     * @param reconciliationDate 对账日期
     * @param reconciliationData 对账数据
     */
    public static void logReconciliation(String paymentType, String reconciliationDate, Object reconciliationData) {
        // 设置业务ID
        if (!StringUtils.isEmpty(reconciliationDate) && !StringUtils.isEmpty(paymentType)) {
            MDCTraceUtils.setBusinessId(paymentType + "_" + reconciliationDate);
        }
        
        logPaymentOperation(PREFIX_RECONCILIATION, paymentType, null, null, reconciliationDate, reconciliationData);
    }
    
    /**
     * 记录支付错误日志
     * 
     * @param paymentType 支付类型
     * @param orderNo 订单号
     * @param errorMessage 错误信息
     * @param e 异常
     */
    public static void logPaymentError(String paymentType, String orderNo, String errorMessage, Throwable e) {
        setBusinessId(orderNo);
        
        if (e != null) {
            PAYMENT_LOGGER.error("{} - 类型: {}, 订单号: {}, 错误信息: {}", 
                    PREFIX_PAYMENT_ERROR, paymentType, orderNo, errorMessage, e);
        } else {
            PAYMENT_LOGGER.error("{} - 类型: {}, 订单号: {}, 错误信息: {}", 
                    PREFIX_PAYMENT_ERROR, paymentType, orderNo, errorMessage);
        }
    }
    
    /**
     * 通用日志记录方法
     */
    private static void logPaymentOperation(String operation, String paymentType, String orderNo, 
                                           String refundNo, String reconciliationDate, Object data) {
        try {
            String dataJson = toJson(data);
            
            if (!StringUtils.isEmpty(refundNo)) {
                // 退款相关日志
                PAYMENT_LOGGER.info("{} - 类型: {}, 订单号: {}, 退款号: {}, 数据: {}", 
                        operation, paymentType, orderNo, refundNo, dataJson);
            } else if (!StringUtils.isEmpty(reconciliationDate)) {
                // 对账相关日志
                PAYMENT_LOGGER.info("{} - 类型: {}, 对账日期: {}, 数据: {}", 
                        operation, paymentType, reconciliationDate, dataJson);
            } else {
                // 支付相关日志
                PAYMENT_LOGGER.info("{} - 类型: {}, 订单号: {}, 数据: {}", 
                        operation, paymentType, orderNo, dataJson);
            }
        } catch (Exception e) {
            PAYMENT_LOGGER.error("记录{}日志异常", operation, e);
        }
    }
    
    /**
     * 设置业务ID
     */
    private static void setBusinessId(String businessId) {
        if (!StringUtils.isEmpty(businessId)) {
            MDCTraceUtils.setBusinessId(businessId);
        }
    }
    
    /**
     * 将对象转换为JSON字符串
     */
    private static String toJson(Object obj) {
        if (obj == null) {
            return "null";
        }
        
        try {
            return OBJECT_MAPPER.writeValueAsString(obj);
        } catch (JsonProcessingException e) {
            return obj.toString();
        }
    }
} 